package cn.dodgeball.java;

import cn.dodgeball.util.Const;
import cn.dodgeball.util.PClass;


import javax.swing.*;
import java.awt.*;
import java.util.Random;

public class Ball extends JPanel implements Runnable {
    private final int radius = Const.ballRadius;
    private boolean isAlive = true;
    private double locationX, locationY;              // 圆心坐标
    private int speedX, speedY;                       // 分速度
    private int width = Const.WIDTH;
    private int height = Const.HEIGHT;
    private final Random random = new Random();       // 随机数对象
    private final Color color = new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));

    public Ball() {
        this.locationX = random.nextInt(width - 2 * radius) + radius;
        this.locationY = random.nextInt(height - 2 * radius) + radius;
        this.speedX = (int) ((random.nextInt(Const.MAX_SPEED_OF_BALL) + 1) * Math.pow(-1, random.nextInt(2)));
        this.speedY = (int) ((random.nextInt(Const.MAX_SPEED_OF_BALL) + 1) * Math.pow(-1, random.nextInt(2)));
        setBounds((int) locationX - radius, (int) locationY - radius, radius * 2, radius * 2);
        setSize(radius * 2, radius * 2);
        setOpaque(false);
    }

    public Ball(int x, int y, int speedX, int speedY) {
        locationX = x;
        locationY = y;
        this.speedX = speedX;
        this.speedY = speedY;
    }

    public void run() {
        while (isAlive) {
            // 判断是小球是否与正方形相撞
            if (Const.isGaming && !Const.isGold && isCrash(PClass.mousePosition.x, PClass.mousePosition.y, Const.squareRadius)) {
                Const.isGaming = false;
                PClass.gamePanel.gameOver();
                System.out.print("撞球出局" + "(" + locationX + "." + locationY + ")" + "(" + PClass.mousePosition.x + "." + PClass.mousePosition.y + ")" + "\n");
            }

            rePaint();
            sleep(10);
        }
    }

    private void sleep(int millis){
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    private void rePaint(){
        // 让小球移动
        locationX += speedX * Const.speedRate;
        locationY += speedY * Const.speedRate;
        setBounds((int) locationX - radius, (int) locationY - radius, radius * 2, radius * 2);

        // 判断小球是否撞墙
        if (locationX - radius <= 0) {
            locationX = radius;
            speedX *= -1;
        } else if (locationX + radius >= width) {
            locationX = width - radius;
            speedX *= -1;
        }
        if (locationY - radius <= 0) {
            locationY = radius;
            speedY *= -1;
        } else if (locationY + radius >= height) {
            locationY = height - radius;
            speedY *= -1;
        }
        // 重绘图像
        repaint();
    }

    private boolean isCrash(int x, int y, int r) {
        double dx = max(locationX - radius - x, 0, x - (locationX + radius));
        double dy = max(locationY - radius - y, 0, y - (locationY + radius));
        return dx * dx + dy * dy < r * r;
    }

    private int max(double x, double y, double z) {
        double max = x;
        if (y > max)
            max = y;
        if (z > max)
            max = z;
        return (int) max;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(color);
        g2d.fillOval(0, 0, radius * 2, radius * 2);
    }

    @Override
    public void removeNotify() {
        super.removeNotify();
        isAlive = false;
    }
}
